package edu.bjtu.supplychain.controller;

import edu.bjtu.supplychain.client.CRUDClient;
import edu.bjtu.supplychain.entity.*;
import edu.bjtu.supplychain.utils.Utils;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;

@RestController
public class TestController {

    @Autowired
    private CRUDClient crudClient;

    public static final Logger logger = LoggerFactory.getLogger(TestController.class.getName());

    @CrossOrigin
    @GetMapping("/" +
            "/{factoryCode}")
    public Object querySeed(@PathVariable("factoryCode") String factoryCode) throws Exception{
        List<SeedFactory> seedFactories = crudClient.selectSeed(factoryCode);
        ResponseData<List<SeedFactory>> res = new ResponseData<>();
        if(seedFactories.size() == 0) {
            res.setCode(0);
            res.setMsg(factoryCode + "的相关数据没有上链！");
        } else {
            res.setCode(1);
            res.setMsg("查询到" + factoryCode + "的链上数据！");
        }
        res.setData(seedFactories);
        return res;
    }

    @CrossOrigin
    @PostMapping("/insertSeed")
    public ResponseData insertSeed(@RequestBody SeedFactory seedFactory){
        logger.info("接受到的数据：{}", seedFactory);
        seedFactory.setLogTime(Utils.getCurrentTimeString());
        ResponseData res = new ResponseData();
        try {
            crudClient.insertSeed(seedFactory);
        } catch (Exception e) {
            res.setCode(0);
            res.setMsg("数据" + seedFactory + "上链失败！");
        }
        res.setCode(1);
        res.setMsg("数据" + seedFactory + "上链成功！");
        return res;
    }

    @CrossOrigin
    @GetMapping("/queryFarm/{factoryCode}")
    public ResponseData selectFarm(@PathVariable("factoryCode") String factoryCode) throws ContractException {
        List<Farm> farms = crudClient.selectFarm(factoryCode);
        ResponseData<List<Farm>> res = new ResponseData<>();
        if(farms.size() == 0) {
            res.setCode(0);
            res.setMsg(factoryCode + "的相关数据没有上链！");
        } else {
            res.setCode(1);
            res.setMsg("查询到" + factoryCode + "的链上数据！");
        }
        res.setData(farms);
        return res;
    }

    @CrossOrigin
    @PostMapping("/insertFarm")
    public ResponseData insertFarm(@RequestBody Farm farm){
        logger.info("接受到的数据：{}", farm);
        farm.setLogTime(Utils.getCurrentTimeString());
        ResponseData res = new ResponseData();
        try {
            crudClient.insertFarm(farm);
        } catch (Exception e) {
            res.setCode(0);
            res.setMsg("数据" + farm + "上链失败！");
        }
        res.setCode(1);
        res.setMsg("数据" + farm + "上链成功！");
        return res;
    }

    @CrossOrigin
    @GetMapping("/queryPlant/{factoryCode}")
    public ResponseData selectPlant(@PathVariable("factoryCode") String factoryCode) throws ContractException {
        List<Plant> plants = crudClient.selectPlant(factoryCode);
        ResponseData<List<Plant>> res = new ResponseData<>();
        if(plants.size() == 0) {
            res.setCode(0);
            res.setMsg(factoryCode + "的相关数据没有上链！");
        } else {
            res.setCode(1);
            res.setMsg("查询到" + factoryCode + "的链上数据！");
        }
        res.setData(plants);
        return res;
    }

    @CrossOrigin
    @PostMapping("/insertPlant")
    public ResponseData insertPlant(@RequestBody Plant plant){
        logger.info("接受到的数据：{}", plant);
        plant.setLogTime(Utils.getCurrentTimeString());
        ResponseData res = new ResponseData();
        try {
            crudClient.insertPlant(plant);
        } catch (Exception e) {
            res.setCode(0);
            res.setMsg("数据" + plant + "上链失败！");
        }
        res.setCode(1);
        res.setMsg("数据" + plant + "上链成功！");
        return res;
    }

    @CrossOrigin
    @GetMapping("/queryInspect/{factoryCode}")
    public ResponseData selectInspect(@PathVariable("factoryCode") String factoryCode) throws ContractException {
        List<Inspect> inspects = crudClient.selectInspect(factoryCode);
        ResponseData<List<Inspect>> res = new ResponseData<>();
        if(inspects.size() == 0) {
            res.setCode(0);
            res.setMsg(factoryCode + "的相关数据没有上链！");
        } else {
            res.setCode(1);
            res.setMsg("查询到" + factoryCode + "的链上数据！");
        }
        res.setData(inspects);
        return res;
    }

    @CrossOrigin
    @PostMapping("/insertInspect")
    public ResponseData insertPlant(@RequestBody Inspect inspect){
        logger.info("接受到的数据：{}", inspect);
        inspect.setLogTime(Utils.getCurrentTimeString());
        ResponseData res = new ResponseData();
        try {
            crudClient.insertInspect(inspect);
        } catch (Exception e) {
            res.setCode(0);
            res.setMsg("数据" + inspect + "上链失败！");
        }
        res.setCode(1);
        res.setMsg("数据" + inspect + "上链成功！");
        return res;
    }

    @CrossOrigin
    @GetMapping("/queryButcher/{factoryCode}")
    public ResponseData selectButcher(@PathVariable("factoryCode") String factoryCode) throws ContractException {
        List<Butcher> butchers = crudClient.selectButcher(factoryCode);
        ResponseData<List<Butcher>> res = new ResponseData<>();
        if(butchers.size() == 0) {
            res.setCode(0);
            res.setMsg(factoryCode + "的相关数据没有上链！");
        } else {
            res.setCode(1);
            res.setMsg("查询到" + factoryCode + "的链上数据！");
        }
        res.setData(butchers);
        return res;
    }

    @CrossOrigin
    @PostMapping("/insertButcher")
    public ResponseData insertButcher(@RequestBody Butcher butcher){
        logger.info("接受到的数据：{}", butcher);
        butcher.setLogTime(Utils.getCurrentTimeString());
        ResponseData res = new ResponseData();
        try {
            crudClient.insertButcher(butcher);
        } catch (Exception e) {
            res.setCode(0);
            res.setMsg("数据" + butcher + "上链失败！");
        }
        res.setCode(1);
        res.setMsg("数据" + butcher + "上链成功！");
        return res;
    }

    @CrossOrigin
    @GetMapping("/queryCarrier/{factoryCode}")
    public ResponseData selectCarrier(@PathVariable("factoryCode") String factoryCode) throws ContractException {
        List<Carrier> carriers = crudClient.selectCarrier(factoryCode);
        ResponseData<List<Carrier>> res = new ResponseData<>();
        if(carriers.size() == 0) {
            res.setCode(0);
            res.setMsg(factoryCode + "的相关数据没有上链！");
        } else {
            res.setCode(1);
            res.setMsg("查询到" + factoryCode + "的链上数据！");
        }
        res.setData(carriers);
        return res;
    }

    @CrossOrigin
    @PostMapping("/insertCarrier")
    public ResponseData insertCarrier(@RequestBody Carrier carrier){
        logger.info("接受到的数据：{}", carrier);
        carrier.setLogTime(Utils.getCurrentTimeString());
        ResponseData res = new ResponseData();
        try {
            crudClient.insertCarrier(carrier);
        } catch (Exception e) {
            res.setCode(0);
            res.setMsg("数据" + carrier + "上链失败！");
        }
        res.setCode(1);
        res.setMsg("数据" + carrier + "上链成功！");
        return res;
    }

    @CrossOrigin
    @GetMapping("/queryTerminal/{factoryCode}")
    public ResponseData selectTerminal(@PathVariable("factoryCode") String factoryCode) throws ContractException {
        List<Terminal> terminals = crudClient.selectTerminal(factoryCode);
        ResponseData<List<Terminal>> res = new ResponseData<>();
        if(terminals.size() == 0) {
            res.setCode(0);
            res.setMsg(factoryCode + "的相关数据没有上链！");
        } else {
            res.setCode(1);
            res.setMsg("查询到" + factoryCode + "的链上数据！");
        }
        res.setData(terminals);
        return res;
    }

    @CrossOrigin
    @PostMapping("/insertTerminal")
    public ResponseData insertTerminal(@RequestBody Terminal terminal){
        logger.info("接受到的数据：{}", terminal);
        terminal.setLogTime(Utils.getCurrentTimeString());
        ResponseData res = new ResponseData();
        try {
            crudClient.insertTerminal(terminal);
        } catch (Exception e) {
            res.setCode(0);
            res.setMsg("数据" + terminal + "上链失败！");
        }
        res.setCode(1);
        res.setMsg("数据" + terminal + "上链成功！");
        return res;
    }

    @CrossOrigin
    @GetMapping("/traceback/{productId}")
    public ResponseData traceback(@PathVariable("productId")String productId) throws ContractException {
        List<Terminal> terminals = crudClient.selectTerminal("t_1");
        List<Carrier> carriers = crudClient.selectCarrier("c_1");
        List<Butcher> butchers = crudClient.selectButcher("b_1");
        List<Inspect> inspects = crudClient.selectInspect("i_1");
        List<Plant> plants = crudClient.selectPlant("p_1");
        List<Farm> farms = crudClient.selectFarm("f_1");
        List<SeedFactory> seedFactories = crudClient.selectSeed("1");

        HashMap<String, Object> traceMsg = new HashMap<>();
        String productType = "";
        String seedId = "";
        String cropId = "";
        for(Terminal t:terminals){
            if(t.getProductId().equals(productId)) {
                traceMsg.put("terminal", t);
                productType = t.getProductType();
                break;
            }
        }
        for(Carrier c:carriers) {
            if(c.getProductId().equals(productId)) {
                traceMsg.put("carrier",c);
                break;
            }
        }
        for(Inspect i:inspects) {
            if(i.getProductId().equals(productId)) {
                traceMsg.put("inspect",i);
                break;
            }
        }
        if(productType.equals("vegetable_product")) {
            for (Plant p:plants) {
                if(p.getProductId().equals(productId)) {
                    traceMsg.put("plant", p);
                    cropId = p.getCropId();
                    break;
                }
            }

        }
        if(productType.equals("meat_product")) {
            for (Butcher b:butchers) {
                if(b.getProductId().equals(productId)) {
                    traceMsg.put("butcher",b);
                    break;
                }
            }
            for (Plant p:plants) {
                if(p.getProductId().equals(productId)) {
                    traceMsg.put("plant",p);
                    cropId = p.getCropId();
                    break;
                }
            }
        }

        for(Farm f:farms) {
            if (f.getCropId().equals(cropId)) {
                if(productType.equals("vegetable_product")) {
                    seedId = f.getSeedId();
                }
                traceMsg.put("farm",f);
                break;
            }
        }
        for(SeedFactory s:seedFactories) {
            if (s.getSeedId().equals(seedId)) {
                traceMsg.put("seedFactory", s);
                break;
            }
        }

        ResponseData data = new ResponseData();
        data.setCode(0);
        data.setData(traceMsg);
        return data;
    }

}
